﻿using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor.Utils
{
    /// <summary>
    /// reveal.js 定义的幻灯片特效字符串。
    /// </summary>
    public class FragmentAction
    {
        static FragmentAction()
        {
            FragmentActionsList.Add(new FragmentAction("fragment fade-out", "dc", "fo", "淡出", "Slide fade out.", "幻灯片淡出。"));

            // 经测试，这几个如果不是用在整段——而是用在片段上——效果基本一样。
            FragmentActionsList.Add(new FragmentAction("fragment", "", "fi", "淡入", "Slide fade in.", "幻灯片淡入。"));
            FragmentActionsList.Add(new FragmentAction("fragment fade-in", "dr", "fi", "淡入", "Slide fade in.", "幻灯片淡入。"));
            FragmentActionsList.Add(new FragmentAction("fragment fade-up", "ds", "fu", "淡上", "Slide up while fading in.", "幻灯片向上淡入。"));
            FragmentActionsList.Add(new FragmentAction("fragment fade-down", "dx", "fd", "淡下", "Slide down while fading in.", "幻灯片向下淡入。"));
            FragmentActionsList.Add(new FragmentAction("fragment fade-left", "dz", "fl", "淡左", "Slide left while fading in.", "幻灯片向左淡入。"));
            FragmentActionsList.Add(new FragmentAction("fragment fade-right", "dy", "fr", "淡右", "Slide right while fading in.", "幻灯片向右淡入。"));

            FragmentActionsList.Add(new FragmentAction("fragment fade-in-then-out", "drdc", "fifo", "淡入淡出", "Fades in, then out on the next step.", "淡入，下一步淡出。"));
            FragmentActionsList.Add(new FragmentAction("fragment fade-in-then-semi-out", "drxc", "fifs", "淡入小出", "Fades in, then to 50% on the next step.", "淡入，下一步缩小到50%。"));

            // 经测试，这两个在用于片段时不起作用。
            FragmentActionsList.Add(new FragmentAction("fragment grow", "fd", "su", "放大", "Scale up.", "放大。"));
            FragmentActionsList.Add(new FragmentAction("fragment shrink", "sx", "sd", "缩小", "Scale down.", "缩小。"));

            // 经测试，即使用于片段，这几个效果也各不一样。
            FragmentActionsList.Add(new FragmentAction("fragment strike", "scx", "st", "删除线", "Strike through.", "删除线。"));
            FragmentActionsList.Add(new FragmentAction("fragment highlight-red", "r", "h", "红", "Turn text red.", "文本变红。"));
            FragmentActionsList.Add(new FragmentAction("fragment highlight-green", "g", "l", "绿", "Turn text green.", "文本变绿。"));
            FragmentActionsList.Add(new FragmentAction("fragment highlight-blue", "b", "u", "蓝", "Turn text blue.", "文本变蓝。"));
            FragmentActionsList.Add(new FragmentAction("fragment highlight-current-red", "rc", "ro", "红出", "Turn text red, then back to original on next step.", "文本变红，下一步恢复。"));
            FragmentActionsList.Add(new FragmentAction("fragment highlight-current-green", "gc", "go", "绿出", "Turn text green, then back to original on next step.", "文本变绿，下一步恢复。"));
            FragmentActionsList.Add(new FragmentAction("fragment highlight-current-blue", "bc", "uo", "蓝出", "Turn text blue, then back to original on next step.", "文本变蓝，下一步恢复。"));
        }

        /// <summary>
        /// 将别名转换为 reveal.js 定义的特效字符串。
        /// </summary>
        /// <param name="oneOfName"></param>
        /// <returns></returns>
        public static string GetFullActionClassName(string oneOfName)
        {
            if (oneOfName == null) return "";
            var alias = oneOfName.Trim(new char[] { ' ', '　', '\t', });
            var trimChars = new char[] { ' ', '　', '\t', };
            var regFragmentHeader = new Regex(@"fragments?[ 　\t]{1,}");  //这是为了防止用户把 fragment 写成 fragments。

            foreach (var fali in FragmentActionsList)
            {
                var lower = oneOfName.ToLower().Trim(trimChars);
                var matchFragmentHeader = regFragmentHeader.Match(lower);
                if (matchFragmentHeader.Success)
                {
                    lower = "fragment " + lower.Substring(matchFragmentHeader.Length).Trim(trimChars);
                }

                if (lower == fali.ClassName) return fali.ClassName;
                if (fali.Alias1 == lower || fali.Alias2 == lower || fali.Alias3 == lower || fali.ClassName == lower || fali.ClassName == ("fragment " + lower)) return fali.ClassName;
            }

            return "[UnKnown]";
        }

        /// <summary>
        /// 某些 reveal.js 特效用在文本片段上是不起作用或者作用完全一样。此时应当统一。
        /// 应当先调用 GetFullActionClassName() 取得 fullName ，再调用本方法。
        /// </summary>
        public static string GetFullSpanActionClassName(string fullName)
        {
            switch (fullName)
            {
                case "fragment grow":
                case "fragment shrink":  // 这两个用在片段上时不起作用
                case "fragment":   // 这个相当于 fade-in
                case "fragment fade-in":
                case "fragment fade-up":
                case "fragment fade-left":
                case "fragment fade-right": return "fragment";  // 这几个用在片段上效果相同
                default: return fullName;
            }
        }

        public static List<FragmentAction> FragmentActionsList { get; } = new List<FragmentAction>();

        /// <summary>
        /// reveal.js 使用的特效信息。
        /// </summary>
        /// <param name="name">特效全称，可用在 html 标签上。例如：class="fragment fade-out"。默认情况下，class="fragment" 是 fade-in（这个不要写）。</param>
        /// <param name="alias1">别名1</param>
        /// <param name="note"></param>
        /// <param name="cnNote"></param>
        public FragmentAction(string name, string alias1, string alias2, string alias3, string note, string cnNote)
        {
            ClassName = name;
            Alias1 = alias1;
            Alias2 = alias2;
            Alias3 = alias3;
            Note = note;
        }

        public string Alias1 { get; }
        public string Alias2 { get; }
        public string Alias3 { get; }
        public string ClassName { get; }
        public string Note { get; }
    }
}
